package com.jiangsong.utils;

import com.jiangsong.utils.base.EmptyOperation;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;

public class AfterCommitExecUtil {

    private static final ExecutorService executor = Executors.newFixedThreadPool(4);


    public static <I> void asyncExecute(Consumer<I> consumer, I input) {

        if (!TransactionSynchronizationManager.isSynchronizationActive()) {
            // 不存在事务
            executor.submit(() -> consumer.accept(input));
            return;
        }

        // 存在事务
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCompletion(int status) {
                if (status == TransactionSynchronization.STATUS_COMMITTED) {
                    // 事务提交完成之后执行
                    executor.submit(() -> consumer.accept(input));
                }
            }
        });
    }

    public static void asyncExecute(EmptyOperation operation) {

        if (!TransactionSynchronizationManager.isSynchronizationActive()) {
            executor.submit(operation::perform);
            return;
        }

        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCompletion(int status) {
                if (status == TransactionSynchronization.STATUS_COMMITTED) {
                    executor.submit(operation::perform);
                }
            }
        });
    }


    public static <I> void syncExecute(Consumer<I> consumer, I input) {

        if (!TransactionSynchronizationManager.isSynchronizationActive()) {
            consumer.accept(input);
            return;
        }

        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCompletion(int status) {
                if (status == TransactionSynchronization.STATUS_COMMITTED) {
                    consumer.accept(input);
                }
            }
        });
    }

    public static void syncExecute(EmptyOperation operation) {

        if (!TransactionSynchronizationManager.isSynchronizationActive()) {
            operation.perform();
            return;
        }

        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCompletion(int status) {
                if (status == TransactionSynchronization.STATUS_COMMITTED) {
                    operation.perform();
                }
            }
        });
    }
}
